//定义store
import { defineStore } from 'pinia'
import { ref, computed } from 'vue';
import axios from 'axios';
import { ElMessage } from 'element-plus';

/**
 * 第一个参数：名字 唯一性
 * 第二个参数：函数，函数的内部可以定义状态的所有内容
 */
export const useTokenStore = defineStore("token", () => {
    //定义状态的内容

    //1.响应式变量
    const token = ref('')
    const tokenExpireTime = ref(0) // token过期时间戳

    // 在store初始化时，尝试从localStorage手动加载token
    try {
        const savedState = JSON.parse(localStorage.getItem('token'));
        if (savedState) {
            token.value = savedState.token;
            tokenExpireTime.value = savedState.tokenExpireTime;
            console.log('从localStorage加载token成功:', token.value ? token.value.substring(0, 15) + '...' : 'null');
        }
    } catch (e) {
        console.error('加载持久化token失败', e);
    }

    // 计算属性：token是否已过期
    const isTokenExpired = computed(() => {
        if (!token.value) return true;
        // 提前5分钟刷新token，避免在操作过程中突然过期
        const currentTime = Date.now();
        const expirationBuffer = 5 * 60 * 1000; // 5分钟
        return tokenExpireTime.value > 0 && currentTime > (tokenExpireTime.value - expirationBuffer);
    })

    // 解析JWT token获取过期时间
    const parseJwt = (token) => {
        try {
            const base64Url = token.split('.')[1];
            const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
            const jsonPayload = decodeURIComponent(atob(base64).split('').map((c) => {
                return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
            }).join(''));
            return JSON.parse(jsonPayload);
        } catch (e) {
            console.error('解析JWT失败', e);
            return null;
        }
    }

    //2.定义一个函数修改token的值
    const setToken = (newToken) => {
        console.log('正在存储token:', newToken ? '有值' : '无值', newToken ? newToken.substring(0, 15) + '...' : '');
        if (!newToken) {
            console.warn('尝试存储空token');
            return;
        }

        token.value = newToken

        // 解析token，获取过期时间
        const payload = parseJwt(newToken);
        if (payload && payload.exp) {
            tokenExpireTime.value = payload.exp * 1000; // 转换为毫秒
            console.log('token过期时间设置为:', new Date(tokenExpireTime.value).toLocaleString());
        } else {
            console.warn('无法解析token过期时间');
        }

        // 手动将token保存到localStorage，作为pinia持久化的备份
        try {
            localStorage.setItem('token', JSON.stringify({
                token: newToken,
                tokenExpireTime: tokenExpireTime.value
            }));
            console.log('token已手动保存到localStorage');
        } catch (e) {
            console.error('token保存到localStorage失败', e);
        }

        // 验证token是否成功存储
        setTimeout(() => {
            console.log('检查token是否成功存储:', !!token.value);
        }, 100);
    }

    //3.定义一个函数 移除token
    const removeToken = () => {
        token.value = ''
        tokenExpireTime.value = 0
    }

    //4.clearToken作为removeToken的别名，保持API一致性
    const clearToken = () => {
        removeToken()
    }

    // 5.刷新token
    const refreshToken = async () => {
        if (!token.value) return false;

        try {
            const response = await axios({
                method: 'post',
                url: '/api/auth/refresh',
                headers: {
                    'Authorization': token.value
                }
            });

            if (response.data.code === 200) {
                const newToken = response.data.data;
                setToken(newToken);
                return true;
            } else {
                ElMessage.error('Token刷新失败，请重新登录');
                removeToken();
                return false;
            }
        } catch (error) {
            console.error('刷新token失败', error);
            ElMessage.error('登录已过期，请重新登录');
            removeToken();
            return false;
        }
    }

    return {
        token,
        tokenExpireTime,
        isTokenExpired,
        setToken,
        removeToken,
        clearToken,
        refreshToken
    }
},
    {
        persist: true //持久化存储
    });